#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2020 Institute of Software, CAS. All rights reserved.
# oepkgs_build_system_utils is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of
# the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF
# ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
# NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.
#
# Original author: Ocean Killer <ocean8192@isrc.iscas.ac.cn>
# Date: 04 Nov 2020

import sys
import os
import abc
import logging
import configparser
import sqlite3
import json
import gnupg

import table_header_map as thm


class _etc_config:
    '''The default config from /etc for this tool set
    '''
    def __init__(self):
        self.const = thm._const
        self.const.config_file = '/etc/oepkgs.conf'
        self.const.config_dir = '/etc/oepkgs.conf.d'

        path_get = lambda k: self.const.config.get('path', k)
        misc_get = lambda k: self.const.config.get('misc', k)

        basepath = None
        try:
            self.const.config = configparser.ConfigParser()
            self.const.config.read(self.const.config_file)
            self.const.basepath = path_get('configs_base')
            self.const.mypubkey = path_get('system_pubkey')
            self.const.database = path_get('database')
            self.const.installation = path_get('exec_prefix')
            self.const.sys_repo_prefix = path_get('yum_repo_base')
            self.const.sys_keyring = path_get('system_keyring_path')
            self.const.sessions_db = path_get('sessions')
            self.const.user_projects = path_get('user_projects')

            self.const.key_passphrase = misc_get('key_passphrase')
            self.const.pm_api_url_base = misc_get('pm_api_url_base')
            self.const.jenkins_cli_jar = misc_get('jenkins_cli_jar')
            self.const.jenkins_url = misc_get('jenkins_url')
            self.const.jenkins_user = misc_get('jenkins_user')
            self.const.jenkins_passphrase = misc_get('jenkins_passphrase')
        except Exception as e:
            logging.error(f'config file error')
            logging.error(e)
            sys.exit(-1)

        # Initializing table header mapper
        if not hasattr(self.const, 'tools_path'):
            thm.base_path_set(
                    os.path.join(
                        self.const.basepath,
                        'tools'
                        )
                    )


class _data_source:
    '''Base class for data source access for oepkgs configuration
    '''
    def __init__(self):
        self.data = {}

    @abc.abstractmethod
    def data_source_set(self, data_source):
        pass

    @abc.abstractmethod
    def value_get(self, key, cons=None):
        pass

    @abc.abstractmethod
    def save(self):
        pass


class _data_source_sqlite3(_data_source):
    '''Class for data source access for sqlite3 database
    '''
    def __init__(self):
        super().__init__()
        self.__db_conn = None
        self.__cursor = None

    def __del__(self):
        if self.__db_conn is not None:
            self.__db_conn.commit()
            self.__db_conn.close()

    def data_source_set(self, dbfile):
        self.__db_conn = sqlite3.connect(dbfile, timeout=10)
        self.__cursor = self.__db_conn.cursor()

    def value_get(self, key, cons=None):
        self.__cursor.execute(f'select {key[0]} from {key[1]}' +
                              f' where {cons[0]}="{cons[1]}";')
        return str(self.__cursor.fetchone()).strip("),'(")

    def table_exist(self, table_name):
        self.__cursor.execute(f'SELECT count(*) FROM \
        sqlite_master WHERE type="table" AND name = "{table_name}";')

        return (self.__cursor.fetchone()[0] >= 1)

    def record_exist(self, table_name, key, value):
        self.__cursor.execute(
            f'SELECT count(*) FROM {table_name} WHERE "{key}"="{value}";'
        )

        return (self.__cursor.fetchone()[0] >= 1)

    def value_set(self,
                  table,
                  key,
                  value,
                  cons_key,
                  cons_value):
        self.sql_run(
            f'UPDATE {table} SET {key}={value} WHERE '
            f'{cons_key}={cons_value};'
        )

    def sql_run(self, cmd):
        self.__cursor.execute(f'{cmd}')

        return self.__cursor.fetchall()

    def db_init(self):
        prj = thm._const.DB["PROJECTS"]
        self.__cursor.execute(
            f'CREATE TABLE projects \
            ({prj["JOB_ID"]} INTEGER PRIMARY KEY AUTOINCREMENT, \
            {prj["JOB_NAME"]} TEXT UNIQUE NOT NULL, \
            {prj["SCM_REPO"]} TEXT NOT NULL, \
            {prj["BRANCH"]} TEXT NOT NULL, \
            {prj["PROJ_TOKEN"]} TEXT, \
            {prj["YUM_REPO"]} TEXT, \
            {prj["USER"]} INTEGER, \
            {prj["SCRATCH_BUILD"]} INTEGER DEFAULT 1, \
            {prj["WEBHOOK_URL"]} TEXT NOT NULL, \
            {prj["BUILD_TAG"]} TEXT, \
            {prj["OS"]} TEXT, \
            {prj["OS_FULL"]} TEXT, \
            {prj["VERSION"]} TEXT, \
            {prj["BUILD_TYPE"]} TEXT, \
            {prj["PACKAGE_NAME"]} TEXT);'
        )

        usr = thm._const.DB["USER"]
        self.__cursor.execute(
            f'CREATE TABLE users \
            ({usr["ID"]} INTEGER PRIMARY KEY AUTOINCREMENT, \
            {usr["NAME"]} TEXT UNIQUE NOT NULL, \
            {usr["REAL_NAME"]} TEXT, \
            {usr["EMAIL"]} TEXT, \
            {usr["API_TOKEN"]} TEXT, \
            {usr["USER_PUBKEY"]} TEXT, \
            {usr["PROJECTS_REPO"]} TEXT, \
            {usr["PROJECTS_BRANCH"]} TEXT, \
            {usr["PASS"]} CHAR(64)), \
            {usr["PASS_NEED_RESET"]} INTEGER);'
        )

    def save(self):
        self.__db_conn.commit()


class _data_source_json(_data_source):
    '''Class for data source access from JSON file
    '''
    def __init__(self):
        super().__init__()
        self.__json_data = None
        self.__filename = None

    def data_source_set(self, filename):
        self.__filename = filename
        with open(filename, 'r') as f:
            self.__json_data = json.load(f)

    def value_get(self, key, cons=None):
        return self.__json_data[key]

    def save(self):
        with open(self.__filename, 'w') as f:
            json.dump(self.__json_data, f, indent=2)

    def json_get(self):
        return self.__json_data


class _gpg_wrapper:
    '''Wrapping gnupg for encrypt/decrypt of content
    '''
    def __init__(self):
        self.__gnupghome = ''
        self.__key_fingerprint = ''


class _oepkgs_config:
    '''Base class indicates oepkgs project's configuration
    '''
    def __init__(self):
        self.__data_source = None

    def data_source_set(self, data_source):
        self.__data_source = data_source

    def value_get(self, key, cons=None):
        return self.__data_source.value_get(key, cons)


class _oepkgs_user_config(_oepkgs_config):
    '''User configuration for oepkgs
    '''
    def __init__(self):
        super().__init__()


class _oepkgs_project_config(_oepkgs_config):
    '''Project configuration for oepkgs
    '''
    def __init__(self):
        super().__init__()


def test_self():
    return 0


if __name__ == '__main__':
    sys.exit(test_self())
